package ebj.common.httpclient.download;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;

import org.omg.CORBA.PUBLIC_MEMBER;
import org.xml.sax.InputSource;

import ebj.common.utils.StringUtils;


public class MultiThreadDownloader {
	public static boolean fileIsDownloadingCompleted(String fileUrl, File localFile) throws MalformedURLException, IOException {
		boolean isCompleted = false;
		URL url = new URL(fileUrl);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setRequestMethod("GET");// 设置请求的方式
		connection.setReadTimeout(5000);// 设置超时的时间
		connection.setConnectTimeout(5000);// 设置链接超时的时间
		connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0");	// 设置请求的头
		int rsp_code = connection.getResponseCode();
		if (200 == rsp_code) {
			int fileLength = connection.getContentLength();
			if (localFile.exists() && localFile.isFile()) {
				long localFileLength = localFile.length();
				if (localFileLength < fileLength) {
					isCompleted = false;
				}else {
					isCompleted = true;
				}
			}
		}
		return isCompleted;
	}

	public static void download(String fileAccessUrl, int threadNum) throws IOException {
		// TODO Auto-generated method stub
		URL url = new URL(fileAccessUrl);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setReadTimeout(50000);
		connection.setRequestMethod("GET");
		int response_code = connection.getResponseCode();
		if (200 == response_code) {
			// 获取网络文件长度
			int fileLength = connection.getContentLength();
			System.out.println("fileTotalSize [" + fileLength + "]bytes.");
			// 创建临时文件，以保存下载数据内容
			File file = new File(getFileName(fileAccessUrl));
			RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rwd");
			randomAccessFile.setLength(fileLength);
			randomAccessFile.close();
			
			// 计算每条线程负责下载的数据块大小
			int m = fileLength % threadNum;
			int n = fileLength / threadNum;
			int blockSize = (m == 0) ? n : (n + 1);
			System.out.println("blockSize [" + blockSize + "]bytes.");
			for (int threadid = 0; threadid < threadNum; threadid++) {
				DownloadThread myThread = new DownloadThread(threadid, blockSize, url, file);
				new Thread(myThread).start();
			}
		}
	}

	private static String getFileName(String url) {
		String fileName = "randomFileName.tmp";
		if (StringUtils.isNotNullOrEmpty(url)) {
			fileName = url.substring(url.lastIndexOf("/") + 1, url.length());
		}
		return fileName;
	}
}

class DownloadThread implements Runnable{
	int threadid;
	int blockSize;
	URL url;
	File file;

	public DownloadThread() {
		super();
		// TODO Auto-generated constructor stub
	}

	public DownloadThread(int threadid, int blockSize, URL url, File file) {
		super();
		this.threadid = threadid;
		this.blockSize = blockSize;
		this.url = url;
		this.file = file;
	}

	public void run() {
		// TODO Auto-generated method stub
		int start = threadid * blockSize; // 计算该线程的下载起始位置
		int end = (threadid + 1) * blockSize - 1; // 计算该线程下载结束位置
		RandomAccessFile randomAccessFile;
		try {
			randomAccessFile = new RandomAccessFile(file, "rwd");
			randomAccessFile.seek(start);
			
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			connection.setReadTimeout(5000);
			connection.setRequestMethod("GET");
			connection.setRequestProperty("Range", String.format("bytes=%s-%s", start, end));
			if (206 == connection.getResponseCode()) {
				InputStream is = connection.getInputStream();
				byte[] bytes = new byte[1024];
				int length = 0;
				while ((length = is.read(bytes)) != -1) {
					randomAccessFile.write(bytes, 0, length);
				}
				randomAccessFile.close();
				is.close();
			}
			System.out.println("线程" + (threadid + 1) + "[" + Thread.currentThread().getName() + "] 已经完成" + (end - start) + "bytes数据下载.");
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
}
